﻿using System;
using System.Net;
using System.IO;
using System.Text;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Collections.Generic;
using System.Windows.Forms;

namespace YTSK.Common
{
    class handleHttp
    {


        #region 通用Get方法，可以处理http与https，返回数据，返回String
        /// <summary>
        /// 通用Get方法，可以处理http与https，返回数据，返回String
        /// </summary>
        /// <param name="url">请求的url地址</param>
        /// <returns>http GET成功后返回的数据，失败抛WebException异常</returns>
        public static string Get(string url)
        {
            System.GC.Collect();
            string result = "";

            HttpWebRequest request = null;
            HttpWebResponse response = null;

            //请求url以获取数据
            try
            {
                //设置最大连接数
                ServicePointManager.DefaultConnectionLimit = 200;
                //设置https验证方式
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback =
                            new RemoteCertificateValidationCallback(CheckValidationResult);
                }

                /***************************************************************
                * 下面设置HttpWebRequest的相关属性
                * ************************************************************/
                request = (HttpWebRequest)WebRequest.Create(url);

                request.Method = "GET";

                //设置代理
                //WebProxy proxy = new WebProxy();
                //proxy.Address = new Uri(WxPayConfig.PROXY_URL);
                //request.Proxy = proxy;

                //获取服务器返回
                response = (HttpWebResponse)request.GetResponse();

                //获取HTTP返回数据
                StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                result = sr.ReadToEnd().Trim();
                sr.Close();
            }
            #region 忽略错误，外层统一处理
            //catch (System.Threading.ThreadAbortException e)
            //{
            //    // Log.Error("HttpService", "Thread - caught ThreadAbortException - resetting.");
            //    System.Threading.Thread.ResetAbort();
            //    throw new Exception(e.ToString());
            //}
            //catch (WebException e)
            //{
            //    // Log.Error("HttpService", e.ToString());
            //    if (e.Status == WebExceptionStatus.ProtocolError)
            //    {
            //        //Log.Error("HttpService", "StatusCode : " + ((HttpWebResponse)e.Response).StatusCode);
            //        //  Log.Error("HttpService", "StatusDescription : " + ((HttpWebResponse)e.Response).StatusDescription);
            //    }
            //    throw new Exception(e.ToString());
            //}
            //catch (Exception e)
            //{
            //    //  Log.Error("HttpService", e.ToString());
            //    throw new Exception( "Common.HandleHttp" e.Message);
            //}
            #endregion
            finally
            {
                #region  关闭连接和流
                if (response != null)
                {
                    response.Close();
                }
                if (request != null)
                {
                    request.Abort();
                }
                #endregion
            }
            return result;
        }
        #endregion

        #region https Get方式访问必须返回证书认证正确
        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            //直接确认，否则打不开
            return true;
        }
        #endregion

        #region 上传文件
        /// <summary>
        /// 上传文件
        /// </summary>
        public static string FileUpload(string m_fileNamePath, string input, string url)
        {

            #region 将文件转成二进制

            FileStream fs = new FileStream(m_fileNamePath, FileMode.Open, FileAccess.Read);
            var fileContentByte = new byte[fs.Length]; // 二进制文件
            fs.Read(fileContentByte, 0, Convert.ToInt32(fs.Length));
            var fileName = fs.Name;
            fs.Close();


            #endregion

            return FileUpload(fileContentByte, fileName, input, url);
        }


        /// <summary>
        /// 上传文件
        /// </summary>
        public static string FileUpload(byte[] fileContentByte, string fileName, string input, string url)
        {


            #region 定义请求体中的内容 并转成二进制
            string modelId = "4f1e2e3d-6231-4b13-96a4-835e5af10394";
            string updateTime = "2016-11-03 14:17:25";
            string encrypt = "f933797503d6e2c36762428a280e0559";
            string boundary = "ceshi";
            string Enter = "\r\n";

            string modelIdStr = "--" + boundary + Enter
                    + "Content-Disposition: form-data; name=\"modelId\"" + Enter + Enter
                    + modelId + Enter;

            string fileContentStr = "--" + boundary + Enter
                    + "Content-Type:application/octet-stream" + Enter
                    + "Content-Disposition: form-data; name=\"fileContent\"; filename=\"" + fileName + "\"" + Enter + Enter;

            string updateTimeStr = Enter + "--" + boundary + Enter
                    + "Content-Disposition: form-data; name=\"updateTime\"" + Enter + Enter
                    + updateTime;

            string encryptStr = Enter + "--" + boundary + Enter
                    + "Content-Disposition: form-data; name=\"encrypt\"" + Enter + Enter
                    + encrypt + Enter + "--" + boundary + "--";


            var modelIdStrByte = Encoding.UTF8.GetBytes(modelIdStr);//modelId所有字符串二进制

            var fileContentStrByte = Encoding.UTF8.GetBytes(fileContentStr);//fileContent一些名称等信息的二进制（不包含文件本身）

            var updateTimeStrByte = Encoding.UTF8.GetBytes(updateTimeStr);//updateTime所有字符串二进制

            var encryptStrByte = Encoding.UTF8.GetBytes(encryptStr);//encrypt所有字符串二进制


            #endregion


            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            request.Method = "POST";
            request.ContentType = "multipart/form-data;boundary=" + boundary;

            Stream myRequestStream = request.GetRequestStream();//定义请求流

            #region 将各个二进制 安顺序写入请求流 modelIdStr -> (fileContentStr + fileContent) -> uodateTimeStr -> encryptStr

            myRequestStream.Write(modelIdStrByte, 0, modelIdStrByte.Length);

            myRequestStream.Write(fileContentStrByte, 0, fileContentStrByte.Length);
            myRequestStream.Write(fileContentByte, 0, fileContentByte.Length);

            myRequestStream.Write(updateTimeStrByte, 0, updateTimeStrByte.Length);

            myRequestStream.Write(encryptStrByte, 0, encryptStrByte.Length);

            #endregion

            var response = request.GetResponse() as HttpWebResponse;
            var instream = response.GetResponseStream();
            var sr = new StreamReader(instream, Encoding.UTF8);
            //返回结果网页（html）代码
            string content = sr.ReadToEnd();
            string err = string.Empty;
            return content;
        }


        #endregion

        #region 通用Post方法,http与https一致字符串
        /// <summary>
        /// 通用Post方法,http与https一致字符串
        /// </summary>
        /// <param name="obj">发送的对象</param>
        /// <param name="url">发送的目标网址</param>
        /// <returns>发送后的返回值</returns>
        public static string Post<T>(T obj, string url)
        {
            var s = Common.handleJSON.Serialize(obj);
            return Post(s, url);
        }
        #endregion

        #region 通用Post方法,http与https一致字符串
        /// <summary>
        /// 通用Post方法,http与https一致字符串
        /// </summary>
        /// <param name="str">发送的字符串</param>
        /// <param name="url">发送的目标网址</param>
        /// <returns>发送后的返回值</returns>
        public static string Post(string str, string url)
        {
            Stream outstream = null;
            Stream instream = null;
            StreamReader sr = null;
            HttpWebResponse response = null;
            HttpWebRequest request = null;
            Encoding encoding = Encoding.UTF8;
            byte[] data = encoding.GetBytes(str);
            // 准备请求...
            try
            {
                // 设置参数
                request = WebRequest.Create(url) as HttpWebRequest;
                CookieContainer cookieContainer = new CookieContainer();
                request.Timeout = 10000000;
                request.CookieContainer = cookieContainer;
                request.AllowAutoRedirect = true;
                request.Method = "POST";
                request.ContentType = "application/x-www-form-urlencoded";
                request.ContentLength = data.Length;
                outstream = request.GetRequestStream();
                outstream.Write(data, 0, data.Length);
                outstream.Close();
                //发送请求并获取相应回应数据
                response = request.GetResponse() as HttpWebResponse;
                //直到request.GetResponse()程序才开始向目标网页发送Post请求
                instream = response.GetResponseStream();
                sr = new StreamReader(instream, encoding);
                //返回结果网页（html）代码
                string content = sr.ReadToEnd();
                string err = string.Empty;
                return content;
            }
            finally
            {
                #region  关闭连接和流
                if (response != null)
                {
                    response.Close();
                }
                if (request != null)
                {
                    request.Abort();
                }
                #endregion
            }
        }
        #endregion


        #region 下载文件
        public static string DownLoadFile(string url)
        {
            WebResponse response = null;
            Stream stream = null;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
            response = request.GetResponse();
            var contenttype = response.ContentType;
            switch (contenttype)
            {
                case "application/json; charset=utf-8":
                    StreamReader sr = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
                    var s = sr.ReadToEnd().Trim();
                    var result = Common.handleJSON.DeserializeResult(s);
                    MessageBox.Show("下载文件时出现出错:" + result.resultdetail);
                    return ""; 

            }

            var desc = response.Headers["Content-Disposition"].ObjToString();
            string fstr = "filename*=UTF-8''";
            int pos1 = desc.IndexOf(fstr);
            string filename = desc.Substring(pos1 + fstr.Length);
            filename = System.Web.HttpUtility.UrlDecode(filename);
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "pdf文件|*.pdf";
            sfd.CheckPathExists = true;
            sfd.FileName = filename;
            sfd.ShowDialog();
            filename = sfd.FileName;
            if (filename.Length == 0) { MessageBox.Show("请输入正确的文件名"); return ""; }
            stream = response.GetResponseStream();
            SaveBinaryFile(response, filename);
            return filename;

        }

        #endregion

        #region 下载文件---

        // <summary>
        /// Save a binary file to disk.
        /// </summary>
        /// <param name="response">The response used to save the file</param>
        // 将二进制文件保存到磁盘
        private static void SaveBinaryFile(WebResponse response, string FileName)
        {
            byte[] buffer = new byte[1024];
            if (File.Exists(FileName))
                File.Delete(FileName);
            Stream outStream = System.IO.File.Create(FileName);
            Stream inStream = response.GetResponseStream();
            int l;
            do
            {
                l = inStream.Read(buffer, 0, buffer.Length);
                if (l > 0)
                    outStream.Write(buffer, 0, l);
            }
            while (l > 0);
            outStream.Close();
            inStream.Close();
        }

        #endregion
    }
}
